#include "llib_version.h"
#define L_VERSION   1120104
#if L_VERSION == LLIB_VERSION_TO_TEST

#include <boost/test/unit_test.hpp>
using namespace boost;

#include <llib.h>
using namespace llib;
using namespace llib::geom;

#include <vector>
using namespace std;

BOOST_AUTO_TEST_SUITE(TriMesh_test_suite)

BOOST_AUTO_TEST_CASE(TriMesh2_test_case_01) {
    const Int32 vertexNum = 15;
    vector<Vec3f> vertexList(vertexNum);
    const Int32 faceNum = 16;
    Vec3i faceList0[faceNum] = { Vec3i(0,1,2), Vec3i(1,3,4), Vec3i(2,4,5), Vec3i(3,6,7),
                                 Vec3i(4,7,8), Vec3i(5,8,9), Vec3i(6,10,11), Vec3i(7,11,12),
                                 Vec3i(8,12,13), Vec3i(9,13,14), Vec3i(1,4,2), Vec3i(3,7,4),
                                 Vec3i(4,8,5), Vec3i(6,11,7), Vec3i(7,12,8), Vec3i(8,13,9) };
    vector<Vec3i> faceIndexList(faceList0, faceList0+faceNum);

    TriMesh model(vertexList, faceIndexList);

    /* vertex, edge, face */
    BOOST_CHECK_EQUAL( model.GetVertexNum(), vertexNum );
    BOOST_CHECK_EQUAL( model.GetEdgeNum(), 30 );
    BOOST_CHECK_EQUAL( model.GetFaceNum(), faceNum );

    /* inner lists */
    const Float* vertexList_float = model.GetVertexList();
    BOOST_CHECK_EQUAL( vertexList_float[0], 0.f );
    BOOST_CHECK_EQUAL( vertexList_float[1], 0.f );
    BOOST_CHECK_EQUAL( vertexList_float[3*2+1], 0.f );
    BOOST_CHECK_EQUAL( vertexList_float[vertexNum * 3 - 1], 0.f );
    const Int32* faceIndexList_int = model.GetFaceVertexIndexList();
    BOOST_CHECK_EQUAL( faceIndexList_int[0], 0 );
    BOOST_CHECK_EQUAL( faceIndexList_int[1], 1 );
    BOOST_CHECK_EQUAL( faceIndexList_int[2], 2 );
    BOOST_CHECK_EQUAL( faceIndexList_int[3*3+0], 3 );
    BOOST_CHECK_EQUAL( faceIndexList_int[3*3+1], 6 );
    BOOST_CHECK_EQUAL( faceIndexList_int[3*3+2], 7 );
    BOOST_CHECK_EQUAL( faceIndexList_int[14*3+0], 7 );
    BOOST_CHECK_EQUAL( faceIndexList_int[14*3+1], 12 );
    BOOST_CHECK_EQUAL( faceIndexList_int[14*3+2], 8 );

    /* face, edge traversal */
    MeshFace face = model.GetFace(0);
    BOOST_CHECK_EQUAL( face.GetIndex(), 0 );
    BOOST_CHECK_EQUAL( face.GetVertex(0).GetIndex(), 0 );
    BOOST_CHECK_EQUAL( face.GetVertex(1).GetIndex(), 1 );
    BOOST_CHECK_EQUAL( face.GetVertex(2).GetIndex(), 2 );
    MeshEdge edge = face.GetEdge(MeshFace::EdgeBC);
    face = edge.GetFace(MeshEdge::FaceRight);
    BOOST_CHECK_EQUAL( face.GetIndex(), 10 );
    edge = face.GetEdge(MeshFace::EdgeAB);
    face = edge.GetFace(MeshEdge::FaceRight);
    BOOST_CHECK_EQUAL( face.GetIndex(), 1 );
    edge = face.GetEdge(MeshFace::EdgeBC);
    face = edge.GetFace(MeshEdge::FaceRight);
    BOOST_CHECK_EQUAL( face.GetIndex(), 11 );
    edge = face.GetEdge(MeshFace::EdgeBC);
    face = edge.GetFace(MeshEdge::FaceLeft);
    BOOST_CHECK_EQUAL( face.GetIndex(), 4 );
    edge = face.GetEdge(MeshFace::EdgeCA);
    face = edge.GetFace(MeshEdge::FaceLeft);
    BOOST_CHECK_EQUAL( face.GetIndex(), 12 );
    edge = face.GetEdge(MeshFace::EdgeCA);
    face = edge.GetFace(MeshEdge::FaceLeft);
    MeshFace face2 = face;
    BOOST_CHECK_EQUAL( face.GetIndex(), 2 );
    edge = face.GetEdge(MeshFace::EdgeAB);
    face = edge.GetFace(MeshEdge::FaceRight);
    BOOST_CHECK_EQUAL( face.GetIndex(), 10 );
    edge = face2.GetEdge(MeshFace::EdgeCA);
    BOOST_CHECK( edge.GetFace(MeshEdge::FaceRight).Valid() );
    BOOST_CHECK( !edge.GetFace(MeshEdge::FaceLeft).Valid() );

    /* model copy */
    TriMesh model2(model);
    BOOST_CHECK_NE( model.GetVertexList(), model2.GetVertexList() );
    BOOST_CHECK_NE( model.GetFaceVertexIndexList(), model2.GetFaceVertexIndexList() );
    BOOST_CHECK_EQUAL( model.GetVertexNum(), model2.GetVertexNum() );
    BOOST_CHECK_EQUAL( model.GetEdgeNum(), model2.GetEdgeNum() );
    BOOST_CHECK_EQUAL( model.GetFaceNum(), model2.GetFaceNum() );

    /* vertex map */
    face = model.GetFace(14);
    Vec3f& v = face.GetVertex(1).GetRef();
    v.x = -1.f;
    v.y = -2.f;
    v.z = -3.f;
    Vec3f v2 = v;
    BOOST_CHECK_EQUAL( model.GetVertex(12).GetRef(), v2 );

}

BOOST_AUTO_TEST_SUITE_END()

#endif
